// Thread functions for BF533
//

#ifndef __THREAD_H__
#define __THREAD_H__

#include <unistd.h>
#include <pthread.h>

#ifdef __cplusplus
extern "C" {
#endif

// NOTE: 1. Each platform has different priority defined
//			in PL8202 lower value has higher priority
//			in WIN32  lower value has lower priority
//			in BF533 lower value has ?? priority
//			so use below to adjust the priority
//		 2. Normally user should not use THREAD_PRIO_IDLE / THREAD_PRIO_TIME_CRITICAL
#define THREAD_PRIO_IDLE			1
#define	THREAD_PRIO_LOWEST			2
#define	THREAD_PRIO_BELOW_NORMAL	3
#define	THREAD_PRIO_NORMAL			4
#define	THREAD_PRIO_ABOVE_NORMAL	5
#define	THREAD_PRIO_HIGHEST			6
#define	THREAD_PRIO_TIME_CRITICAL	7

typedef pthread_t			TThread;
typedef pthread_mutex_t		TMutex;

typedef void*				TThreadFuncArg;
typedef void*				TThreadFuncRtn;
#define FUNC_API
typedef TThreadFuncRtn (*TThreadFuncPtr)(TThreadFuncArg);


/////////////////////////////////////////////////////////////////////////////
// Thread functions

// Create a thread
void os_ThreadCreate(int priority, TThread *thread, TThreadFuncPtr func, \
					 TThreadFuncArg func_arg, int stack_size, void *stack_addr);

void os_SetThreadPriority(TThread thread, int priority);

int  os_GetThreadPriority(TThread thread);

// Allow a thread to terminate itself
void os_ThreadExit();

// Suspend the specified thread and the thread's suspend count is incremented
// NOTE: scheduler will never run a thread with a non-zero suspend counter. 
void os_ThreadSuspend(TThread thread);

// Decrement the suspend counter
// NOTE: when the suspend count is decremented to zero, the execution of the
//		 thread is resumed.
void os_ThreadResume(TThread thread);

// Force the calling thread to relinquish use of its processor, and to wait
// in the run queue before it is scheduled again
// NOTE: pl1061 not supported?
void os_ThreadYield();

// Wait for thread termination 
void os_ThreadJoin(TThread thread);


/////////////////////////////////////////////////////////////////////////////
// Mutex

// Initialize a mutex
// NOTE: if a mutex is no longer required and there are no threads waiting
//       on it then call os_MutexDestroy.
void os_MutexInit(TMutex *mutex);

// Destroy a mutex
// NOTE: attempting to destroy a locked mutex results in undefined behavior.
void os_MutexDestroy(TMutex *mutex);

// Lock a mutex
// NOTE: return after claiming the mutex lock, blocking if another thread
//		 currently owns the mutex.
void os_MutexLock(TMutex *mutex);

// Unlock a mutex
// NOTE: the current owner of a mutex should call os_MutexUnlock when a lock
//		 is no longer required. This operation must be performed by the owner,
//		 not by another thread.
void os_MutexUnlock(TMutex *mutex);

#ifdef __cplusplus
}
#endif

#endif // __THREAD_H__
